package com.angel.bo.admin.service.impl;

import com.angel.bo.admin.constants.DictCodeConstant;
import com.angel.bo.admin.service.MenuService;
import com.angel.bo.admin.service.PermissionService;
import com.angel.bo.admin.service.RoleService;
import com.angel.bo.admin.service.UserRoleService;
import com.angel.bo.auth.client.jwt.AuthUtil;
import com.angel.bo.beans.admin.dto.MenuTreeDto;
import com.angel.bo.beans.admin.entity.Menu;
import com.angel.bo.beans.admin.entity.Permission;
import com.angel.bo.beans.admin.entity.Role;
import com.angel.bo.beans.admin.entity.UserRole;
import com.angel.bo.beans.admin.vo.SavePermissionVo;
import com.angel.bo.beans.admin.vo.UserRoleVo;
import com.angel.bo.cache.annotation.ServiceCache;
import com.angel.bo.cache.constant.ServiceCacheActionEnum;
import com.angel.bo.cache.model.CacheType;
import com.angel.bo.common.context.CommonContextHandler;
import com.angel.bo.common.msg.WebReturn;
import com.angel.bo.common.service.impl.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.angel.bo.admin.mapper.PermissionMapper;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import static com.angel.bo.common.util.SpringUtil.getBean;


/**
 * 
 *
 * @author ${author}
 * @email haibo.mei@ge.com
 * @date 2018-02-01 14:32:20
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class PermissionServiceImpl extends BaseServiceImpl<PermissionMapper,Permission> implements PermissionService {

    @Autowired
    private MenuService menuService;


    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private AuthUtil authUtil;

    @Autowired
    private RoleService roleService;


    /**
     * 用户授权菜单-获取 所选角色 或者 （所选角色 + 所选角色实例）
     * @param userRole
     * @return
     */
    @Override
    @SuppressWarnings("ALL")
    public WebReturn getPermissionList(UserRole userRole) {


        List<UserRole> userRoles = new ArrayList<>();
        List<Permission> permissions = new ArrayList<>();

        if(userRole.getUserRoleId() != null){
            //当对角色实例授权菜单和按钮的时候，菜单和按钮应该由两部分组成，1个角色实例上的
            // 1 个角色实例对应的
            //先查询角色上的
            UserRole userRoleEntity = userRoleService.selectById(userRole.getUserRoleId());
            userRoles.add(userRoleEntity);
            //查询角色实例上的授权菜单&按钮
            Permission searchPermission = new Permission();
            searchPermission.setPermissionEntity(DictCodeConstant.PERMISSION_ENTITY_2);
            searchPermission.setPermissionEntityKey(userRole.getUserRoleId());
            searchPermission.setPermissionAccessEntity(DictCodeConstant.PERMISSION_ACCESS_ENTITY_1);

            List<Permission> userRolePermission = super.selectList(searchPermission);
            for (Permission permission : userRolePermission) {
                permission.setUserRolePermission(true);
            }

            permissions.addAll(userRolePermission);

        }else  if(userRole.getUserId() != null){
            //查询所有角色
            UserRole searchRole = new UserRole();
            searchRole.setUserId(userRole.getUserId());
            //查询有效的角色实例
            searchRole.setState(DictCodeConstant.USER_ROLE_STATE_1);
            userRoles = userRoleService.selectList(searchRole);
        }else{
            userRoles.add(userRole);
        }

        for (UserRole role : userRoles) {
            Permission searchPermission = new Permission();
            searchPermission.setPermissionEntity(DictCodeConstant.PERMISSION_ENTITY_1);
            searchPermission.setPermissionEntityKey(role.getRoleId());
            searchPermission.setPermissionAccessEntity(DictCodeConstant.PERMISSION_ACCESS_ENTITY_1);
            permissions.addAll(super.selectList(searchPermission));
        }


        List<Menu> menus = menuService.selectListAll();
        List<MenuTreeDto> menuTreeDtos = new ArrayList<>();
        for (Menu mu : menus) {
            MenuTreeDto menuTreeDto = new MenuTreeDto();
            menuTreeDto.setMenuId(mu.getMenuId());
            menuTreeDto.setTitle(mu.getMenuName());
            menuTreeDto.setParentMenuId(mu.getMenuParentId());
            menuTreeDto.setPath(mu.getMenuUrl());
            menuTreeDto.setMenuType(mu.getMenuType());
            menuTreeDto.setMenuIcon(mu.getMenuIcon());
            for (Permission permission : permissions) {

                if(userRole.getUserRoleId() != null){
                    if(permission.getPermissionAccessEntityKey().equals(menuTreeDto.getMenuId()+"")){
                        menuTreeDto.setChecked(true);
                        if(!permission.isUserRolePermission()){
                            menuTreeDto.setDisabled(true);
                        }
                    }
                }else{
                    if(permission.getPermissionAccessEntityKey().equals(menuTreeDto.getMenuId()+"")){
                        menuTreeDto.setChecked(true);
                    }
                }

            }
            menuTreeDtos.add(menuTreeDto);
        }
        //递归调用，完成树的拼装
        ArrayList<MenuTreeDto> treeList = new ArrayList<>();
        for (MenuTreeDto treeMenu : menuTreeDtos) {
            if(treeMenu.getParentMenuId() != null){
                continue;
            }
            MenuTreeDto menuTreeDto = findChildren(treeMenu,menuTreeDtos,false);
            if(menuTreeDto.getParentMenuId() == null){
                treeList.add(menuTreeDto);
            }

        }

        WebReturn webReturn = new WebReturn();
        webReturn.setData(treeList);

        return webReturn;
    }

    /**
     * 给角色授权
     *
     * @param savePermissionVo
     * @return
     */
    @Override
    public WebReturn saveThePermissionToRole(SavePermissionVo savePermissionVo) {


        if(savePermissionVo.getUserRoleId() != null){
            Permission searchPermission = new Permission();
            //如果是角色实例不为空，则删除已经授权角色实例权限
            searchPermission.setPermissionEntity(DictCodeConstant.PERMISSION_ENTITY_2);
            searchPermission.setPermissionEntityKey(savePermissionVo.getUserRoleId());
            searchPermission.setPermissionAccessEntity(DictCodeConstant.PERMISSION_ACCESS_ENTITY_1);
            this.delete(searchPermission);

            String [] menuIdStrs = savePermissionVo.getMenuIds().split(",");
            Set<Integer> menuIds = new HashSet();
            for (String menuIdStr : menuIdStrs) {
                if("".equals(menuIdStr)){
                    continue;
                }
                menuIds.add(Integer.parseInt(menuIdStr));
            }
            for (Integer menuId : menuIds) {
                Permission entity = new Permission();
                entity.setPermissionEntity(DictCodeConstant.PERMISSION_ENTITY_2);
                entity.setPermissionEntityKey(savePermissionVo.getUserRoleId());
                entity.setPermissionAccessEntity(DictCodeConstant.PERMISSION_ACCESS_ENTITY_1);
                entity.setPermissionAccessEntityKey(menuId+"");
                entity.setCreateDate(new Date());
                entity.setCreateUserId(authUtil.getUserIdFromToken());
                this.insert(entity);
            }

        }else if(savePermissionVo.getRoleId() != null){
            //首先删除此角色授权过的菜单
            //查找权限表信息
            Permission searchPermission = new Permission();
            searchPermission.setPermissionEntity(DictCodeConstant.PERMISSION_ENTITY_1);
            searchPermission.setPermissionEntityKey(savePermissionVo.getRoleId());
            searchPermission.setPermissionAccessEntity(DictCodeConstant.PERMISSION_ACCESS_ENTITY_1);
            this.delete(searchPermission);


            String [] menuIdStrs = savePermissionVo.getMenuIds().split(",");
            Set<Integer> menuIds = new HashSet();
            for (String menuIdStr : menuIdStrs) {
                if("".equals(menuIdStr)){
                    continue;
                }
                menuIds.add(Integer.parseInt(menuIdStr));
            }
            for (Integer menuId : menuIds) {
                Permission entity = new Permission();
                entity.setPermissionEntity(DictCodeConstant.PERMISSION_ENTITY_1);
                entity.setPermissionEntityKey(savePermissionVo.getRoleId());
                entity.setPermissionAccessEntity(DictCodeConstant.PERMISSION_ACCESS_ENTITY_1);
                entity.setPermissionAccessEntityKey(menuId+"");
                entity.setCreateUserId(authUtil.getUserIdFromToken());
                entity.setCreateDate(new Date());
                this.insert(entity);
            }
        }



        WebReturn webReturn = new WebReturn();
        webReturn.setMsg("授权成功");

        return webReturn;
    }

    @Override
    @SuppressWarnings("ALL")
    /**
     * 登录时获取用户所有的权限 所有角色 + 所有角色实例
     */
    public WebReturn getPermissionListMenu(UserRole userRole) {
        List<UserRole> userRoles = new ArrayList<>();
        List<Permission> permissions = new ArrayList<>();
        if(userRole.getUserId() != null){
            //查询所有角色
            UserRole searchRole = new UserRole();
            searchRole.setUserId(userRole.getUserId());
            //查询有效的角色实例
            searchRole.setState(DictCodeConstant.USER_ROLE_STATE_1);
            userRoles = userRoleService.selectList(searchRole);
        }else{
            userRoles.add(userRole);
        }

        for (UserRole role : userRoles) {
            Permission searchPermission = new Permission();
            searchPermission.setPermissionEntity(DictCodeConstant.PERMISSION_ENTITY_1);
            searchPermission.setPermissionEntityKey(role.getRoleId());
            searchPermission.setPermissionAccessEntity(DictCodeConstant.PERMISSION_ACCESS_ENTITY_1);
            permissions.addAll(super.selectList(searchPermission));
            //查询所有角色实例 授权的菜单和按钮
            searchPermission.setPermissionEntity(DictCodeConstant.PERMISSION_ENTITY_2);
            searchPermission.setPermissionEntityKey(role.getUserRoleId());
            searchPermission.setPermissionAccessEntity(DictCodeConstant.PERMISSION_ACCESS_ENTITY_1);
            permissions.addAll(super.selectList(searchPermission));
        }


        List<Menu> menus = menuService.selectListAll();
        List<MenuTreeDto> menuTreeDtos = new ArrayList<>();
        for (Menu mu : menus) {
            MenuTreeDto menuTreeDto = new MenuTreeDto();
            menuTreeDto.setMenuId(mu.getMenuId());
            menuTreeDto.setTitle(mu.getMenuName());
            menuTreeDto.setParentMenuId(mu.getMenuParentId());
            menuTreeDto.setPath(mu.getMenuUrl());
            menuTreeDto.setMenuType(mu.getMenuType());
            menuTreeDto.setMenuIcon(mu.getMenuIcon());
            for (Permission permission : permissions) {
                if(permission.getPermissionAccessEntityKey().equals(menuTreeDto.getMenuId()+"")){
                    menuTreeDto.setChecked(true);
                    menuTreeDtos.add(menuTreeDto);
                }
            }

        }
        //递归调用，完成树的拼装
        ArrayList<MenuTreeDto> treeList = new ArrayList<>();
        for (MenuTreeDto treeMenu : menuTreeDtos) {
            if(treeMenu.getParentMenuId() != null){
                continue;
            }
            MenuTreeDto menuTreeDto = findChildren(treeMenu,menuTreeDtos,true);
            if(menuTreeDto.getParentMenuId() == null){
                treeList.add(menuTreeDto);
            }

        }

        WebReturn webReturn = new WebReturn();
        webReturn.setData(treeList);

        return webReturn;
    }

    /**
     * 获取角色实例列表
     *
     * @param userRoleVo
     * @return
     */
    @Override
    public WebReturn getUserRolePage(UserRoleVo userRoleVo) {
        return userRoleService.getUserRolePage(userRoleVo);
    }

    /**
     * 给角色实例授权
     *
     * @param savePermissionVo
     * @return
     */
    @Override
    public WebReturn saveThePermissionDataToUserRole(SavePermissionVo savePermissionVo) {

        //1,先将配置的所有角色实例的数据权限删除
        Permission searchPermission = new Permission();
        //如果是角色实例不为空，则删除已经授权角色实例权限
        searchPermission.setPermissionEntity(DictCodeConstant.PERMISSION_ENTITY_2);
        searchPermission.setPermissionEntityKey(savePermissionVo.getUserRoleId());
        searchPermission.setPermissionAccessEntity(DictCodeConstant.PERMISSION_ACCESS_ENTITY_2);
        this.delete(searchPermission);

        UserRole userRole = userRoleService.selectById(savePermissionVo.getUserRoleId());
        if(null == savePermissionVo.getOrgIds() || "".equals(savePermissionVo.getOrgIds())){

            Role role = roleService.selectById(userRole.getRoleId());
            if(null != role){
                //这里面存逗号是为了保持数据一致性，因为前台传的数据就带有逗号
                savePermissionVo.setOrgIds(role.getOrganizationId()+",");
            }
        }

        Permission entity = new Permission();
        entity.setPermissionEntity(DictCodeConstant.PERMISSION_ENTITY_2);
        entity.setPermissionEntityKey(savePermissionVo.getUserRoleId());
        entity.setPermissionAccessEntity(DictCodeConstant.PERMISSION_ACCESS_ENTITY_2);
        entity.setPermissionAccessEntityKey(savePermissionVo.getDataPermissionModel()+"|"+savePermissionVo.getOrgIds());
        entity.setCreateUserId(authUtil.getUserIdFromToken());
        entity.setCreateDate(new Date());
        this.insert(entity);

        PermissionService permissionService = getBean(PermissionService.class);
        permissionService.initThePermissionDataByCurrentUser(userRole);

        return new WebReturn("数据权限配置成功");
    }

    /**
     * 获取角色实例授权的数据权限
     *
     * @param savePermissionVo
     * @return
     */
    @Override
    public WebReturn getThePermissionDataByUserRole(SavePermissionVo savePermissionVo) {


        Permission searchPermission = new Permission();
        //如果是角色实例不为空，则删除已经授权角色实例权限
        searchPermission.setPermissionEntity(DictCodeConstant.PERMISSION_ENTITY_2);
        searchPermission.setPermissionEntityKey(savePermissionVo.getUserRoleId());
        searchPermission.setPermissionAccessEntity(DictCodeConstant.PERMISSION_ACCESS_ENTITY_2);
        Permission permissionData = this.selectOne(searchPermission);
        if(null == permissionData){
            return new WebReturn();
        }
        //数据权限
        String permissionDataStr = permissionData.getPermissionAccessEntityKey();
        if(null != permissionDataStr){
            String permissionModel = permissionDataStr.split("\\|")[0];
            String orgIds = permissionDataStr.split("\\|")[1];
            savePermissionVo.setOrgIds(orgIds);
            savePermissionVo.setDataPermissionModel(Integer.parseInt(permissionModel));

        }

        return new WebReturn(savePermissionVo);
    }

    /**
     * 获取当前用户所有的数据权限
     *
     * @return
     */
    @SuppressWarnings("ALL")
    @Override
    @ServiceCache(action = ServiceCacheActionEnum.GET,scope = CacheType.USER_PERMISSION_DATA_INFO,keyExpression = "#userRole.userId")
    public WebReturn getThePermissionDataByCurrentUser(UserRole userRole) {
        //此处数据从缓存里取出，所以不存在代码
        return new WebReturn();
    }


    /**
     * 获取当前用户所有的数据权限
     *
     * @return
     */
    @SuppressWarnings("ALL")
    @Override
    @ServiceCache(action = ServiceCacheActionEnum.UPDATE,scope = CacheType.USER_PERMISSION_DATA_INFO,keyExpression = "#userRole.userId")
    public WebReturn initThePermissionDataByCurrentUser(UserRole userRole) {

        /**
         * 当前用户的ID
         */
        Integer userId = userRole.getUserId();
        //查询所有角色实例
        UserRole searchRole = new UserRole();
        searchRole.setUserId(userId);
        //查询有效的角色实例
        searchRole.setState(DictCodeConstant.USER_ROLE_STATE_1);
        List<UserRole> userRoles = userRoleService.selectList(searchRole);

        //返回值
        WebReturn webReturn = new WebReturn();

        //分别列出三种权限
        String belongAndSubOrg = "";
        String onlyBelongOrg = "";
        String onlySelfCreate = "";


        for (UserRole userRoleU : userRoles) {
            Permission searchPermission = new Permission();
            //如果是角色实例不为空，则删除已经授权角色实例权限
            searchPermission.setPermissionEntity(DictCodeConstant.PERMISSION_ENTITY_2);
            searchPermission.setPermissionEntityKey(userRoleU.getUserRoleId());
            searchPermission.setPermissionAccessEntity(DictCodeConstant.PERMISSION_ACCESS_ENTITY_2);
            Permission permissionData = this.selectOne(searchPermission);
            if(null != permissionData){
                String orgIds = permissionData.getPermissionAccessEntityKey().split("\\|")[1];
                int permissionModel = Integer.parseInt(permissionData.getPermissionAccessEntityKey().split("\\|")[0]);
                //判断权限-有1吗
                if(permissionModel == DictCodeConstant.DATA_PERMISSION_TYPE_1){
                    webReturn.setData("");
                    //如果有1则不考虑其他情况了
                    return webReturn;
                }
                //判断是否有2和4
                else if(permissionModel == DictCodeConstant.DATA_PERMISSION_TYPE_2 || permissionModel == DictCodeConstant.DATA_PERMISSION_TYPE_4){
                    //把 2 和 4 的权限收集起来
                    belongAndSubOrg = belongAndSubOrg + orgIds;
                    continue;
                }
                else if(permissionModel == DictCodeConstant.DATA_PERMISSION_TYPE_3 || permissionModel == DictCodeConstant.DATA_PERMISSION_TYPE_5){
                    //把 3 和 5 的权限收集起来
                    onlyBelongOrg = onlyBelongOrg + orgIds;
                    continue;
                }
                else if(permissionModel == DictCodeConstant.DATA_PERMISSION_TYPE_6 ){
                    //把 6 的权限收集起来
                    onlySelfCreate = userId+"";
                    continue;
                }
            }
        }

        if(!"".equals(belongAndSubOrg)){

            //这里应该用递归的，麻痹MYSQL 没有递归函数，愁死我了

            webReturn.setData("WHERE exists(SELECT 1 " +
                    "             FROM base_user permssionBu LEFT JOIN base_organization org ON org.organization_id = permssionBu.organization_id " +
                    "             WHERE org.organization_id IN (" + belongAndSubOrg.substring(0,belongAndSubOrg.length()-1) +
                    ") AND " +
                    "                   (permissionDataTable.create_user_id = permssionBu.user_id OR permissionDataTable.create_user_id IS NULL))");
            return webReturn;
        }
        if(!"".equals(onlyBelongOrg)){
            webReturn.setData("WHERE exists(SELECT 1 " +
                    "             FROM base_user permssionBu LEFT JOIN base_organization org ON org.organization_id = permssionBu.organization_id " +
                    "             WHERE org.organization_id IN (" + onlyBelongOrg.substring(0,onlyBelongOrg.length()-1) +
                    ") AND " +
                    "                   (permissionDataTable.create_user_id = permssionBu.user_id OR permissionDataTable.create_user_id IS NULL))");
            return webReturn;
        }

        webReturn.setData("WHERE permissionDataTable.create_user_id = " +onlySelfCreate);

        return webReturn;
    }


    private MenuTreeDto findChildren(MenuTreeDto menuTreeDto, List<MenuTreeDto> treeMenus,boolean checked){

        for (MenuTreeDto treeMenu : treeMenus) {
            if(menuTreeDto.getMenuId().equals(treeMenu.getParentMenuId())){
                if(!treeMenu.isChecked() && !checked){
                    menuTreeDto.setChecked(false);
                }
                if(menuTreeDto.getChildren() == null){
                    menuTreeDto.setChildren(new ArrayList<MenuTreeDto>());
                }
                menuTreeDto.getChildren().add(findChildren(treeMenu,treeMenus,checked));
            }
        }

        return menuTreeDto;
    }
}



